import Card from '@/components/Card';
import Description from '@/components/Description';
import EchartsComponent, { MyChartOption } from '@/components/EchartsComponent';
import type { ProColumns } from '@/components/Pro';
import { ProTable } from '@/components/Pro';
import { getEmptyOptions } from '@/dictionary';
import {
  cycleLifeControllerGetCycleLife,
  cycleLifeControllerGetCycleLifeRow,
} from '@/services/ess/cycleLife';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import type { DatePickerProps } from 'antd';
import { Button, DatePicker, Flex, Form, Popover, Radio, Space, Spin } from 'antd';
import dayjs, { Dayjs } from 'dayjs';
import React, { useEffect, useRef, useState } from 'react';
import styles from '../index.less';

type DataType = {
  date: string;
  stationCompareCellModel: string | number;
  stationModelSoh: string | number;
  stationCompareYesterday: string | number;
};
type dateOptionType = {
  label: string;
  value: string;
};
type formType = {
  dateType: string;
  attenuationDate: Dayjs[];
};
type ChartPropsType = {
  chartOptions: API.ReportTable;
  suggestions: string;
};
type IProps = {
  chartInfo: ChartPropsType;
  chartsLoading: boolean;
};
const StationCharts: React.FC<IProps> = (props) => {
  const intl = useIntl();
  const { chartInfo, chartsLoading } = props;
  const [loadingToken, setLoadingToken] = useState(false);
  const chartRef = useRef(null);
  const [chartOptions, setChartOptions] = useState<MyChartOption>();
  const { RangePicker } = DatePicker;
  const [timePicker, setTimePicker] = useState('date');
  const nowDate = dayjs().subtract(1, 'day').format('YYYY-MM-DD');
  const [stationParams, setStationParams] = useState<formType>({
    dateType: 'D',
    attenuationDate: [dayjs().subtract(1, 'month'), dayjs().add(1, 'month')],
  });
  const dateMap = new Map<string, string>([
    ['D', intl.formatMessage({ id: 'global.dayS' })],
    ['M', intl.formatMessage({ id: 'global.month' })],
    ['Y', intl.formatMessage({ id: 'global.year' })],
  ]);
  const dateOption: dateOptionType[] = [
    {
      label: intl.formatMessage({ id: 'global.day' }),
      value: 'D',
    },
    {
      label: intl.formatMessage({ id: 'global.month' }),
      value: 'M',
    },
    {
      label: intl.formatMessage({ id: 'global.year' }),
      value: 'Y',
    },
  ];
  const tableColumns: ProColumns<DataType>[] = [
    {
      dataIndex: 'date',
      key: 'date',
      hideInSearch: true,
      title: () => {
        return (
          <div
            style={{
              backgroundColor: '#1A6CFE',
              color: '#FFFFFF',
              padding: '10px',
            }}
          >
            <div>{intl.formatMessage({ id: 'global.date' })}</div>
          </div>
        );
      },
    },
    {
      title: () => {
        return (
          <div
            style={{
              backgroundColor: '#59C3F4',
              color: '#fff',
              padding: '10px',
            }}
          >
            {intl.formatMessage({ id: 'batteryVoltage.SOHPlant' })}
          </div>
        );
      },
      dataIndex: 'stationModelSoh',
      key: 'stationModelSoh',
      hideInSearch: true,
    },
    {
      title: () => {
        return (
          <div
            style={{
              backgroundColor: '#56D433',
              color: '#fff',
              padding: '10px',
            }}
          >
            {intl.formatMessage({ id: 'batteryVoltage.SOHPlantModel' })}
          </div>
        );
      },
      dataIndex: 'stationCompareCellModel',
      key: 'stationCompareCellModel',
      hideInSearch: true,
    },
    {
      title: () => {
        return (
          <div
            style={{
              backgroundColor: '#FFD50C',
              color: '#fff',
              padding: '10px',
            }}
          >
            {stationParams.dateType === 'D'
              ? intl.formatMessage({ id: 'batteryVoltage.SOHPlantDiff' })
              : stationParams.dateType === 'M'
              ? intl.formatMessage({ id: 'batteryVoltage.SOHPlantDiffMonth' })
              : intl.formatMessage({ id: 'batteryVoltage.SOHPlantDiffYear' })}
          </div>
        );
      },
      dataIndex: 'stationCompareYesterday',
      key: 'stationCompareYesterday',
      hideInSearch: true,
    },
  ];
  /**
   * 获得系列名称
   * @param seriesName
   */
  const getSeriesName = (axisValue: string, seriesName: string, dateType: string): string => {
    const dateStringMap = new Map<string, string>([
      ['D', intl.formatMessage({ id: 'batteryVoltage.SOHDiffPastDay' })],
      ['M', intl.formatMessage({ id: 'batteryVoltage.SOHDiffPastMonth' })],
      ['Y', intl.formatMessage({ id: 'batteryVoltage.SOHDiffPastYear' })],
    ]);
    const dateNowStringMap = new Map<string, string>([
      ['D', intl.formatMessage({ id: 'batteryVoltage.SOHDiffAllPastDay' })],
      ['M', intl.formatMessage({ id: 'batteryVoltage.SOHDiffAllPastMonth' })],
      ['Y', intl.formatMessage({ id: 'batteryVoltage.SOHDiffAllPastYear' })],
    ]);
    const nowDate =
      dateType === 'D'
        ? dayjs().format('YYYY-MM-DD')
        : dateType === 'M'
        ? dayjs().format('YYYY-MM')
        : dayjs().format('YYYY');
    return axisValue > nowDate
      ? dateStringMap.get(dateType)
      : axisValue === nowDate
      ? dateNowStringMap.get(dateType)
      : seriesName;
  };
  /**
   * 获得图表
   * @param options
   * @param dateType
   * @param timeInterval
   */
  const getOptions = (
    options: API.ReportTable,
    dateType: string,
    timeInterval: number = 3,
  ): MyChartOption => {
    const yAxis3 = JSON.parse(
      JSON.stringify(
        options?.yaxis[1]?.points.map(() => {
          return undefined;
        }),
      ),
    );
    return {
      tooltip: {
        trigger: 'axis',
        formatter: function (params) {
          let text = params.map((item: any) => {
            return (
              item.value !== undefined &&
              item.marker +
                '' +
                (item.seriesIndex === 3
                  ? getSeriesName(item.axisValue, item.seriesName, dateType)
                  : item.seriesName) +
                ' ' +
                item.value +
                '%'
            );
          });
          return params[0].axisValue + '<br/>' + text.filter((item) => item).join('<br/>') + '';
        },
      },
      legend: {
        top: 20,
        right: 0,
        icon: 'rect',
        data: [
          { name: options.yaxis[0].title },
          { name: options.yaxis[1].title },
          { name: options.yaxis[2].title },
        ],
      },
      grid: {
        left: '3%',
        right: '2%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: [
        {
          type: 'category',
          data: options.xaxis,
          axisTick: {
            alignWithLabel: true,
          },
          axisLabel: {
            interval: timeInterval,
            formatter: function (params) {
              return dateType === 'D'
                ? params.slice(5, 10)
                : dateType === 'M'
                ? params.slice(0, 7)
                : params.slice(0, 4) + intl.formatMessage({ id: 'global.yearS' });
            },
          },
        },
      ],
      yAxis: [
        {
          type: 'value',
        },
      ],
      series: [
        {
          type: 'line',
          name: options.yaxis[0].points?.length > 0 ? options.yaxis[0].title : '',
          data: options.yaxis[0].points.map((item) => {
            return item.yaxis;
          }),
          showSymbol: false,
        },
        {
          type: 'line',
          name: options.yaxis[1].points?.length > 0 ? options.yaxis[1].title : '',
          data: options.yaxis[1].points.map((item) => {
            return item.yaxis;
          }),
          showSymbol: false,
        },
        {
          type: 'line',
          name: options.yaxis[2].points?.length > 0 ? options.yaxis[2].title : '',
          showSymbol: false,
          lineStyle: {
            type: 'dashed',
          },
          data: [
            ...yAxis3,
            ...options.yaxis[2].points.map((item) => {
              return item.yaxis;
            }),
          ],
        },
        {
          type: 'line',
          name: options.yaxis[3].title,
          data: options.yaxis[3].points.map((item) => {
            return item.yaxis;
          }),
          legendHoverLink: false,
          showSymbol: false,
          lineStyle: {
            opacity: 0,
          },
        },
      ],
    };
  };
  /**
   * 根据日期和单位控制走势图的x轴间隔
   * @param dateType
   * @param timeRange
   */
  const getTimeDiff = (dateType, timeRange: Dayjs[]): number => {
    let timeInterval = 2;
    if (dateType === 'D') {
      const diff = timeRange[1].diff(timeRange[0], 'day');
      timeInterval =
        diff <= 10 ? 1 : diff > 10 && diff <= 31 ? 1 : diff > 31 && diff <= 100 ? 3 : 11;
    } else if (dateType === 'M') {
      const diff = timeRange[1].diff(timeRange[0], 'month');
      timeInterval = diff > 0 && diff <= 31 ? 0 : 3;
    } else {
      timeInterval = 1;
    }
    return timeInterval;
  };
  /**
   * 限制时间选择范围
   * @param current
   * @param from
   */
  const disabledDate: DatePickerProps['disabledDate'] = (current, { from }) => {
    if (from) {
      if (stationParams.dateType === 'D') {
        return Math.abs(current.diff(from, 'days')) >= 365;
      } else {
        return false;
      }
    }
    return false;
  };

  const getDescriptionText = (dateType: string, dateMap: Map<string, string>, intl: any) => {
    const dateTypeText = dateMap.get(dateType);
    if (dateType === 'D') {
      return intl.formatMessage({ id: 'description.day' }, { dateType: dateTypeText });
    } else if (dateType === 'M') {
      return intl.formatMessage({ id: 'description.month' }, { dateType: dateTypeText });
    } else if (dateType === 'Y') {
      return intl.formatMessage({ id: 'description.year' }, { dateType: dateTypeText });
    }
    return '';
  };

  useEffect(() => {
    if (chartInfo?.chartOptions) {
      chartRef?.current?.instance().clear();
      setChartOptions(getOptions(chartInfo?.chartOptions, stationParams.dateType));
    } else {
      chartRef?.current?.instance().clear();
      setChartOptions(getEmptyOptions());
    }
  }, [chartInfo]);
  useEffect(() => {
    setLoadingToken(chartsLoading);
  }, [chartsLoading]);
  return (
    <>
      <Card
        title={intl.formatMessage({ id: 'batteryVoltage.cycle.sohReduceChart' })}
        style={{ border: 'none' }}
        extra={
          <Popover
            title={false}
            content={
              <div>
                <Card
                  title={intl.formatMessage({ id: 'batteryVoltage.cycleTitle' })}
                  style={{ width: '500px' }}
                >
                  <Flex vertical={true}>
                    <div>{intl.formatMessage({ id: 'batteryVoltage.cycleS1' })}</div>
                    <div>{intl.formatMessage({ id: 'batteryVoltage.cycleS2' })}</div>
                    <div>{intl.formatMessage({ id: 'batteryVoltage.cycleS3' })}</div>
                    <div>{intl.formatMessage({ id: 'batteryVoltage.cycleS4' })}</div>
                    <h4>{intl.formatMessage({ id: 'batteryVoltage.cycleS6' })}</h4>
                    <Description
                      bordered={true}
                      items={[
                        {
                          key: '1',
                          label: intl.formatMessage({ id: 'batteryVoltage.cycleS5' }),
                          children: '≥5%',
                        },
                      ]}
                    ></Description>
                  </Flex>
                </Card>
              </div>
            }
            placement="bottomRight"
          >
            <a href="#">
              <QuestionCircleOutlined />
              &nbsp;{intl.formatMessage({ id: 'batteryVoltage.vol.standard' })}
            </a>
          </Popover>
        }
      >
        <div className={styles.chartContent}>
          <div>
            <Form layout="inline">
              <Form.Item style={{ marginRight: 60 }}>
                <Radio.Group
                  buttonStyle="solid"
                  value={stationParams.dateType}
                  onChange={(e) => {
                    setTimePicker(
                      e.target.value === 'D' ? 'date' : e.target.value === 'M' ? 'month' : 'year',
                    );
                    const params = {
                      unit: e.target.value,
                      startDate:
                        e.target.value === 'D'
                          ? dayjs().subtract(1, 'month').format('YYYY-MM-DD')
                          : e.target.value === 'M'
                          ? dayjs().subtract(6, 'month').format('YYYY-MM')
                          : dayjs().subtract(5, 'year').format('YYYY'),
                      endDate:
                        e.target.value === 'D'
                          ? dayjs().add(1, 'month').format('YYYY-MM-DD')
                          : e.target.value === 'M'
                          ? dayjs().add(6, 'month').format('YYYY-MM')
                          : dayjs().add(5, 'year').format('YYYY'),
                    };
                    const dateRange =
                      e.target.value === 'D'
                        ? [dayjs().subtract(1, 'month'), dayjs().add(1, 'month')]
                        : e.target.value === 'M'
                        ? [dayjs().subtract(6, 'month'), dayjs().add(6, 'month')]
                        : [dayjs().subtract(5, 'year'), dayjs().add(5, 'year')];
                    setStationParams({
                      dateType: e.target.value,
                      attenuationDate: dateRange,
                    });
                    setLoadingToken(true);
                    cycleLifeControllerGetCycleLife(params)
                      .then((res) => {
                        if (res.success) {
                          chartRef?.current?.instance().clear();
                          setChartOptions(
                            getOptions(
                              res?.data?.stationSohTable,
                              e.target.value,
                              getTimeDiff(e.target.value, dateRange),
                            ),
                          );
                          setLoadingToken(false);
                        } else {
                          setLoadingToken(false);
                        }
                      })
                      .catch(() => {
                        setLoadingToken(false);
                      });
                  }}
                >
                  {dateOption.map((item) => (
                    <Radio.Button key={item.value} value={item.value}>
                      {item.label}
                    </Radio.Button>
                  ))}
                </Radio.Group>
              </Form.Item>
              <Form.Item label={intl.formatMessage({ id: 'batteryVoltage.decay' })}>
                <RangePicker
                  disabledDate={disabledDate}
                  minDate={
                    stationParams.dateType === 'Y'
                      ? dayjs().subtract(20, 'year')
                      : dayjs().subtract(3, 'year')
                  }
                  maxDate={
                    stationParams.dateType === 'D'
                      ? dayjs().add(180, 'day')
                      : stationParams.dateType === 'M'
                      ? dayjs().add(1, 'year')
                      : dayjs().add(20, 'year')
                  }
                  picker={timePicker}
                  value={stationParams.attenuationDate}
                  onCalendarChange={(dates, dateStrings, info) => {
                    if (info.range === 'end') {
                      setStationParams({
                        dateType: stationParams.dateType,
                        attenuationDate: dates[0] > dates[1] ? [dates[1], dates[0]] : dates,
                      });
                    }
                  }}
                />
              </Form.Item>
              <Form.Item>
                <Space>
                  <Button
                    type="primary"
                    htmlType="submit"
                    onClick={() => {
                      const params = {
                        unit: stationParams.dateType,
                        startDate:
                          stationParams.dateType === 'D'
                            ? dayjs(stationParams.attenuationDate[0]).format('YYYY-MM-DD')
                            : stationParams.dateType === 'M'
                            ? dayjs(stationParams.attenuationDate[0]).format('YYYY-MM')
                            : dayjs(stationParams.attenuationDate[0]).format('YYYY'),
                        endDate:
                          stationParams.dateType === 'D'
                            ? dayjs(stationParams.attenuationDate[1]).format('YYYY-MM-DD')
                            : stationParams.dateType === 'M'
                            ? dayjs(stationParams.attenuationDate[1]).format('YYYY-MM')
                            : dayjs(stationParams.attenuationDate[1]).format('YYYY'),
                      };
                      setLoadingToken(true);
                      cycleLifeControllerGetCycleLife(params)
                        .then((res) => {
                          if (res.success) {
                            chartRef?.current?.instance().clear();
                            setChartOptions(
                              getOptions(
                                res?.data?.stationSohTable,
                                stationParams.dateType,
                                getTimeDiff(stationParams.dateType, stationParams.attenuationDate),
                              ),
                            );
                            setLoadingToken(false);
                          } else {
                            setLoadingToken(false);
                          }
                        })
                        .catch(() => {
                          setLoadingToken(false);
                        });
                    }}
                  >
                    {intl.formatMessage({ id: 'batteryVoltage.vol.search' })}
                  </Button>
                  {/*<Button*/}
                  {/*  htmlType="reset"*/}
                  {/*  onClick={() => {*/}
                  {/*    setTimePicker('date');*/}
                  {/*    setStationParams({*/}
                  {/*      dateType: 'D',*/}
                  {/*      attenuationDate: [dayjs().subtract(1, 'month'), dayjs().add(1, 'month')],*/}
                  {/*    });*/}
                  {/*    const params = {*/}
                  {/*      unit: 'D',*/}
                  {/*      startDate: dayjs().subtract(1, 'month').format('YYYY-MM-DD'),*/}
                  {/*      endDate: dayjs().add(1, 'month').format('YYYY-MM-DD'),*/}
                  {/*    };*/}
                  {/*    cycleLifeControllerGetCycleLife(params).then((res) => {*/}
                  {/*      if (res.success) {*/}
                  {/*        chartRef?.current?.instance().clear();*/}
                  {/*        setChartOptions(getOptions(res?.data?.stationSohTable));*/}
                  {/*      }*/}
                  {/*    });*/}
                  {/*  }}*/}
                  {/*>*/}
                  {/*  重置*/}
                  {/*</Button>*/}
                </Space>
              </Form.Item>
            </Form>
          </div>
          <div>
            <Spin spinning={loadingToken}>
              <EchartsComponent
                ref={chartRef}
                option={chartOptions}
                height={400}
              ></EchartsComponent>
            </Spin>
          </div>
        </div>
      </Card>
      <Card
        style={{ border: 'none' }}
        title={
          <div>
            {intl.formatMessage({ id: 'batteryVoltage.cycle.sohTrendChart' })}
            <span style={{ fontWeight: 'normal', fontSize: 13 }}>
              &nbsp;&nbsp;(&nbsp;{intl.formatMessage({ id: 'batteryVoltage.cycle.as' })}
              {nowDate}&nbsp;)
            </span>
          </div>
        }
      >
        <div>
          <ProTable
            rowKey={'pageIndex'}
            columns={tableColumns}
            search={false}
            params={{ stationParams, chartInfo }}
            className={styles.chartTable}
            request={async (values) => {
              const { stationParams } = values;
              if (values.chartInfo) {
                const params = {
                  current: values.current,
                  pageSize: values.pageSize,
                  unit: stationParams.dateType,
                  startDate:
                    stationParams.dateType === 'D'
                      ? dayjs(stationParams.attenuationDate[0]).format('YYYY-MM-DD')
                      : stationParams.dateType === 'M'
                      ? dayjs(stationParams.attenuationDate[0]).format('YYYY-MM')
                      : dayjs(stationParams.attenuationDate[0]).format('YYYY'),
                  endDate:
                    stationParams.dateType === 'D'
                      ? dayjs(stationParams.attenuationDate[1]).format('YYYY-MM-DD')
                      : stationParams.dateType === 'M'
                      ? dayjs(stationParams.attenuationDate[1]).format('YYYY-MM')
                      : dayjs(stationParams.attenuationDate[1]).format('YYYY'),
                };
                return await cycleLifeControllerGetCycleLifeRow(params);
              }
            }}
          ></ProTable>
        </div>
        <div className={styles.description}>
          <div>{getDescriptionText(stationParams.dateType, dateMap, intl)}</div>
          <div>
            {intl.formatMessage({ id: 'batteryVoltage.concluded' })}
            {chartInfo?.suggestions}
          </div>
        </div>
      </Card>
    </>
  );
};

export default StationCharts;
